package com.datagateway.controller;

import com.datagateway.component.ConfigHotReloadManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 配置热更新控制器
 * 提供配置热更新的API接口
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@RestController
@RequestMapping("/api/config")
public class ConfigHotReloadController {

    @Autowired
    private ConfigHotReloadManager configHotReloadManager;

    /**
     * 获取所有配置
     * 
     * @return 配置信息
     */
    @GetMapping("/all")
    public Map<String, Object> getAllConfigs() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> configs = configHotReloadManager.getAllConfigs();
            
            result.put("success", true);
            result.put("configs", configs);
            result.put("configCount", configs.size());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取配置失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取指定配置
     * 
     * @param key 配置键
     * @return 配置值
     */
    @GetMapping("/{key}")
    public Map<String, Object> getConfig(@PathVariable String key) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Object value = configHotReloadManager.getConfig(key);
            
            result.put("success", true);
            result.put("key", key);
            result.put("value", value);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取配置失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取配置热更新状态
     * 
     * @return 热更新状态
     */
    @GetMapping("/hot-reload/status")
    public Map<String, Object> getHotReloadStatus() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean enabled = configHotReloadManager.isHotReloadEnabled();
            ConfigHotReloadManager.ConfigHotReloadStatistics statistics = configHotReloadManager.getStatistics();
            
            result.put("success", true);
            result.put("hotReloadEnabled", enabled);
            result.put("statistics", statistics);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取热更新状态失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 启用/禁用配置热更新
     * 
     * @param request 热更新控制请求
     * @return 操作结果
     */
    @PostMapping("/hot-reload/toggle")
    public Map<String, Object> toggleHotReload(@RequestBody HotReloadToggleRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            configHotReloadManager.setHotReloadEnabled(request.isEnabled());
            
            result.put("success", true);
            result.put("hotReloadEnabled", request.isEnabled());
            result.put("message", "配置热更新已" + (request.isEnabled() ? "启用" : "禁用"));
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "切换热更新状态失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 注册配置变更监听器
     * 
     * @param request 监听器注册请求
     * @return 操作结果
     */
    @PostMapping("/listener/register")
    public Map<String, Object> registerConfigListener(@RequestBody ConfigListenerRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 创建监听器
            ConfigHotReloadManager.ConfigChangeListener listener = (key, oldValue, newValue) -> {
                // 这里可以实现具体的监听逻辑
                System.out.println("配置变更: " + key + " = " + oldValue + " -> " + newValue);
            };
            
            // 注册监听器
            configHotReloadManager.registerConfigChangeListener(request.getConfigKey(), listener);
            
            result.put("success", true);
            result.put("configKey", request.getConfigKey());
            result.put("message", "配置监听器注册成功");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "注册配置监听器失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取配置分类信息
     * 
     * @return 配置分类
     */
    @GetMapping("/categories")
    public Map<String, Object> getConfigCategories() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> categories = new HashMap<>();
            
            // Kafka配置
            Map<String, Object> kafkaConfigs = new HashMap<>();
            kafkaConfigs.put("bootstrap-servers", configHotReloadManager.getConfig("kafka.bootstrap-servers"));
            kafkaConfigs.put("group-id", configHotReloadManager.getConfig("kafka.consumer.group-id"));
            kafkaConfigs.put("auto-offset-reset", configHotReloadManager.getConfig("kafka.consumer.auto-offset-reset"));
            kafkaConfigs.put("max-poll-records", configHotReloadManager.getConfig("kafka.consumer.max-poll-records"));
            categories.put("kafka", kafkaConfigs);
            
            // Hive配置
            Map<String, Object> hiveConfigs = new HashMap<>();
            hiveConfigs.put("jdbc-url", configHotReloadManager.getConfig("hive.jdbc.url"));
            hiveConfigs.put("username", configHotReloadManager.getConfig("hive.jdbc.username"));
            hiveConfigs.put("batch-size", configHotReloadManager.getConfig("hive.batch.size"));
            hiveConfigs.put("batch-timeout", configHotReloadManager.getConfig("hive.batch.timeout"));
            categories.put("hive", hiveConfigs);
            
            // Groovy配置
            Map<String, Object> groovyConfigs = new HashMap<>();
            groovyConfigs.put("script-path", configHotReloadManager.getConfig("groovy.script.path"));
            groovyConfigs.put("cache-enabled", configHotReloadManager.getConfig("groovy.script.cache.enabled"));
            groovyConfigs.put("cache-size", configHotReloadManager.getConfig("groovy.script.cache.size"));
            categories.put("groovy", groovyConfigs);
            
            // 告警配置
            Map<String, Object> alertConfigs = new HashMap<>();
            alertConfigs.put("mail-enabled", configHotReloadManager.getConfig("alert.mail.enabled"));
            alertConfigs.put("smtp-host", configHotReloadManager.getConfig("alert.mail.smtp.host"));
            alertConfigs.put("smtp-port", configHotReloadManager.getConfig("alert.mail.smtp.port"));
            alertConfigs.put("recipients", configHotReloadManager.getConfig("alert.mail.recipients"));
            categories.put("alert", alertConfigs);
            
            result.put("success", true);
            result.put("categories", categories);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取配置分类失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取配置热更新统计信息
     * 
     * @return 统计信息
     */
    @GetMapping("/statistics")
    public Map<String, Object> getConfigStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ConfigHotReloadManager.ConfigHotReloadStatistics statistics = configHotReloadManager.getStatistics();
            
            result.put("success", true);
            result.put("statistics", statistics);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取配置统计失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 验证配置值
     * 
     * @param request 配置验证请求
     * @return 验证结果
     */
    @PostMapping("/validate")
    public Map<String, Object> validateConfig(@RequestBody ConfigValidationRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean valid = validateConfigValue(request.getKey(), request.getValue());
            
            result.put("success", true);
            result.put("key", request.getKey());
            result.put("value", request.getValue());
            result.put("valid", valid);
            result.put("message", valid ? "配置值有效" : "配置值无效");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "验证配置失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 验证配置值
     * 
     * @param key 配置键
     * @param value 配置值
     * @return 是否有效
     */
    private boolean validateConfigValue(String key, Object value) {
        if (key == null || value == null) {
            return false;
        }
        
        // 根据配置键进行特定验证
        switch (key) {
            case "kafka.bootstrap-servers":
                return value.toString().contains(":");
            case "kafka.consumer.max-poll-records":
                try {
                    int maxPollRecords = Integer.parseInt(value.toString());
                    return maxPollRecords > 0 && maxPollRecords <= 1000;
                } catch (NumberFormatException e) {
                    return false;
                }
            case "hive.batch.size":
                try {
                    int batchSize = Integer.parseInt(value.toString());
                    return batchSize > 0 && batchSize <= 10000;
                } catch (NumberFormatException e) {
                    return false;
                }
            case "hive.batch.timeout":
                try {
                    int timeout = Integer.parseInt(value.toString());
                    return timeout > 0 && timeout <= 300000; // 5分钟
                } catch (NumberFormatException e) {
                    return false;
                }
            case "alert.mail.smtp.port":
                try {
                    int port = Integer.parseInt(value.toString());
                    return port > 0 && port <= 65535;
                } catch (NumberFormatException e) {
                    return false;
                }
            default:
                return true; // 默认认为有效
        }
    }

    /**
     * 热更新控制请求类
     */
    public static class HotReloadToggleRequest {
        private boolean enabled;

        // Getter和Setter方法
        public boolean isEnabled() { return enabled; }
        public void setEnabled(boolean enabled) { this.enabled = enabled; }
    }

    /**
     * 配置监听器请求类
     */
    public static class ConfigListenerRequest {
        private String configKey;

        // Getter和Setter方法
        public String getConfigKey() { return configKey; }
        public void setConfigKey(String configKey) { this.configKey = configKey; }
    }

    /**
     * 配置验证请求类
     */
    public static class ConfigValidationRequest {
        private String key;
        private Object value;

        // Getter和Setter方法
        public String getKey() { return key; }
        public void setKey(String key) { this.key = key; }
        
        public Object getValue() { return value; }
        public void setValue(Object value) { this.value = value; }
    }
}
